﻿#include "graphtool.h"
#include "monitortool.h"
#include"soundtool.h"

#include <string>
#include <sstream>
#include "appear.h"

using namespace std;

bool init_window() {
    initgraph(width, height);
    setbkcolor(WHITE);
    cleardevice();
    return true;
}

// 辅助函数：将 std::string 转换为 LPCTSTR (const char*)
LPCTSTR stringToLPCTSTR(const std::string& str) {
    return str.c_str();
}

// 辅助函数：将 int 转换为字符串
std::string intToString(int value) {
    std::ostringstream oss;
    oss << value;
    return oss.str();
}



/*
* 负责人：析
* 渲染玩家血条
* 传入：int x - 血条X坐标, int y - 血条Y坐标,
*       int width - 血条宽度, int height - 血条高度,
*       int currentLife - 当前生命值, int maxLife - 最大生命值
* 绘制血条背景和前景（根据生命值比例）
* 返回：无
*/
// 血条绘制函数 - 使用 outtextxy 而不是 drawtext
void render_health_bar(int x, int y, int w, int h, int cur, int max) {
    // 设置合适的字体大小 - 基于血条高度
    int fontSize = max(8, h - 4); // 确保字体不会太大或太小
    settextstyle(fontSize, 0, _T("宋体"));
    // 背景
    setfillcolor(RGB(200, 200, 200));
    solidrectangle(x, y, x + w, y + h);

    // 血量
    setfillcolor(RED);
    solidrectangle(x, y, x + w * cur / max, y + h);

    // 文本
    char text[20];
    sprintf_s(text, "%d/%d", cur, max);
    settextcolor(BLACK);
    outtextxy(x + (w - textwidth(text)) / 2, y + (h - textheight(text)) / 2, text);

    // 钥匙
    char text2[50];
    sprintf_s(text2, "钥匙*%d", P1.bag.num);
    settextcolor(BLACK);
    outtextxy(x + (w - textwidth(text2)) / 2+100, y + (h - textheight(text2)) / 2, text2);
}

void render_main_menu() {
    // 绘制背景
    IMAGE img_menubg;
    loadimage(&img_menubg, "res\\menubkg.png", 1300, 684);
    BeginBatchDraw();
    putimage(0, 0, &img_menubg);

    // 绘制标题
    settextstyle(40, 0, _T("宋体"));
    settextcolor(BLACK);
    setbkmode(TRANSPARENT);
    outtextxy(550, 50, _T("榴莲勇者"));

    // 绘制装饰线
    setlinecolor(WHITE);
    line(500, 120, 800, 120);

    settextstyle(30, 0, _T("宋体"));
    // 绘制所有按钮
    draw_button(550, 220, 200, 50, "开始游戏", WHITE);
    draw_button(550, 290, 200, 50, "游戏设置", WHITE);
    draw_button(550, 360, 200, 50, "游戏介绍", WHITE);
    draw_button(550, 430, 200, 50, "退出游戏", WHITE);

    FlushBatchDraw();
    // 修改部分：使用循环处理所有待处理的鼠标消息
    ExMessage msg;
    // 循环处理所有鼠标消息，避免消息堆积导致响应慢
    while (peekmessage(&msg, EX_MOUSE)) {
        if (msg.message == WM_LBUTTONDOWN) {
            if (check_collision(550, 220, 200, 50, msg.x, msg.y, 1, 1)) {
                state = 1;
                switch_page(currentGameState, PLAYING);
                return;
            }
            else if (check_collision(550, 290, 200, 50, msg.x, msg.y, 1, 1)) {
                switch_page(currentGameState, SET);
                return;
            }
            else if (check_collision(550, 360, 200, 50, msg.x, msg.y, 1, 1)) {
                switch_page(currentGameState, INTRODUCE);
                return;
            }
            else if (check_collision(550, 430, 200, 50, msg.x, msg.y, 1, 1)) {
                switch_page(currentGameState, BREAK);
                return;
            }
        }
    }

   
}


//  ---------- 进行

//绘制城镇
void drowtown() {
    IMAGE townMap;
    IMAGE img;
    IMAGE img1;
    IMAGE img_npc_1;
    IMAGE img_npc_11;
    IMAGE img_npc_2;
    IMAGE img_npc_21;
    // 加载资源（确保图片路径正确，与代码文件同目录）

    loadimage(&townMap, _T("res\\background1.png"));
    loadimage(&img, _T("res\\p.png"), 35, 28);
    loadimage(&img1, _T("res\\p1.png"), 35, 28);
    loadimage(&img_npc_1, _T("res\\npc.png"), 35, 28);
    loadimage(&img_npc_11, _T("res\\npc1.png"), 35, 28);
    loadimage(&img_npc_2, _T("res\\npc.png"), 35, 28);
    loadimage(&img_npc_21, _T("res\\npc1.png"), 35, 28);

    int mapW = townMap.getwidth();
    int mapH = townMap.getheight();

    //initgraph(mapW, mapH, EX_SHOWCONSOLE);  // 初始化城镇窗口
    setbkcolor(WHITE);
    cleardevice();

   

    // 角色初始位置（确保在地图内）
    P1.x = 610;
    P1.y = 611;
    //障碍物
    vector<barrier>barriers1 = { {0,0,550,270},{720,0,580,270},{0,360,560,325},{715,365,585,319},{540,0,176,70} };

    bool needRedraw = true;  // 按需重绘标记（解决卡顿核心）

    ExMessage msg;
    while (true) {
        // 检测场景切换，退出当前循环
        if (state != 1) {
            break;
        }

        int oldX = P1.x;  // 保存原始位置
        int oldY = P1.y;
        bool is_change_pos = true;  // 默认允许移动

        // 处理消息（键盘+鼠标）
        if (peekmessage(&msg, EX_KEY)) {
            // 键盘事件：移动角色
            
            if (msg.message == WM_KEYDOWN) {
                
                switch (msg.vkcode) {
                case 'W': case 'w': P1.y -= 5; break;
                case 'S': case 's': P1.y += 5; break;
                case 'A': case 'a': P1.x -= 5; break;
                case 'D': case 'd': P1.x += 5; break;
                case VK_ESCAPE: state = 5; break;       // 退出
                }
                if ((msg.vkcode == 't' || msg.vkcode == 'T') && (check_collision(600, 100, 35, 28, P1.x, P1.y, 35, 28) || check_collision(100, 290, 35, 28, P1.x, P1.y, 35, 28))) {
                    //跳转render_dialog(const string & dialogText, int npcId)
                    //为优化，返回
                    //play_sound_effect("succeed_joininggame_sound_or_takeup.MP3");
                    state = 0;
                    return;
                }
            }
        }
        // 传送
        if (check_collision(1120, 260, 50, 50, P1.x, P1.y, 35, 28)) {
            state = 2;  // 切换到森林场景
            return;
        }
        

        // 1. 边界检查（防止角色出界）
        if (P1.x < 0 || P1.x  > 1300 ||P1.y < 0 || P1.y  > 684) {   // 用角色高度判断下边界
            is_change_pos = false;
        }

        // 2. 障碍物碰撞检测（核心修复：只要碰一个就禁止移动）
        if (is_change_pos) {  // 先判断边界再检测障碍物
            for (const auto& b : barriers1) {
                // 角色与障碍物碰撞检测（角色x,y,宽35,高28）
                if (check_collision(b.x, b.y, b.w, b.h, P1.x, P1.y, 35, 28)) {
                    is_change_pos = false;
                    break;  // 碰一个就跳出循环，不再检查
                }
            }
        }

        // 3. 重置位置（如果移动无效）
        if (!is_change_pos) {
            P1.x = oldX;
            P1.y = oldY;
        }

        // 4. 重绘（关键修复：始终绘制地图、角色、UI，避免元素消失）
        
        putimage(0, 0, &townMap);  // 绘制地图
        putimage(P1.x, P1.y, &img, SRCAND);   // 绘制角色（透明处理）
        putimage(P1.x, P1.y, &img1, SRCPAINT);
        putimage(600, 100, &img_npc_1, SRCAND);   // 绘制角色（透明处理）
        putimage(600, 100, &img_npc_11, SRCPAINT);
        putimage(100, 290, &img_npc_2, SRCAND);   // 绘制角色（透明处理）
        putimage(100, 290, &img_npc_21, SRCPAINT);
        draw_button(1120, 260, 50, 50, "森林", Color(200, 200, 200));  // 始终显示按钮
        render_health_bar(10, 10, 100, 20, P1.lifelenth, 100);  // 始终显示血条
        FlushBatchDraw(); // 立即刷新

        
        Sleep(16);  // 控制帧率（≈60帧）
    }
}


//绘制森林


void drowtrees() {
    IMAGE img_bg;
    IMAGE img_role;
    IMAGE img_role1;
    IMAGE img_item_1;
    IMAGE img_item_11;
    /*IMAGE img_item_2;
    IMAGE img_item_21;
    IMAGE img_item_3;
    IMAGE img_item_31;*/
    IMAGE img_moving_npc;
    IMAGE img_moving_npc1;

    
    
    P1.x = 100; //地图1的初始为1,2初始为680，3为610
    P1.y = 120;//地图1的初始为110,2初始为605，3为611
    int speed = 5;
    int minion_x = 650;
    int minion_y = 0;
    int dir = 1;
    vector<barrier>barriers = { {0,0,500,108},{503,0,100,330},{0,170,440,510},{430,380,180,300},{714,0,585,684} };

    loadimage(&img_bg, "res\\background2.png", 1300, 684);
    loadimage(&img_moving_npc, "res\\minion.png", 35, 28);
    loadimage(&img_moving_npc1, "res\\minion1.png", 35, 28);
    loadimage(&img_role, "res\\p.png", 35, 28);
    loadimage(&img_role1, "res\\p1.png", 35, 28);
    loadimage(&img_item_1, "res\\medical.png", 35, 28);
    loadimage(&img_item_11, "res\\medical1.png", 35, 28);
    /*loadimage(&img_item_2, "res\\medical.png", 35, 28);
    loadimage(&img_item_21, "res\\medical1.png", 35, 28);
    loadimage(&img_item_3, "res\\medical.png", 35, 28);
    loadimage(&img_item_31, "res\\medical1.png", 35, 28);*/
    /*loadimage(&img_npc, "res\\npc.png", 35, 28);
    loadimage(&img_npc1, "res\\npc1.png", 35, 28);*/

    ExMessage msg;
    bool c = false;
    BeginBatchDraw();
    while (true) {
        if (state != 2) {
            
            return;
        }
        int oldx = P1.x;
        int oldy = P1.y;
        if (minion_y > 665 || minion_y < 0) {
            dir = (-1) * dir;
        }
        minion_y += dir;

        if (peekmessage(&msg, EX_KEY))
        {
            if (msg.message == WM_KEYDOWN) {
                switch (msg.vkcode)  // 获取按下的键值
                {
                case 'w':
                case'W':
                    P1.y -= speed;
                    
                    break;
                case 's':
                case'S':
                    P1.y += speed;
                    
                    break;
                case 'a':
                case'A':
                    P1.x -= speed;
                    
                    break;
                case 'd':
                case'D':
                    P1.x += speed;
                    
                    break;
                case VK_ESCAPE: state = 5; break;
                }
            }
            //else if (msg.message == WM_LBUTTONDOWN) {
            //    // 检测是否点击「返回城镇」按钮（坐标100,50，尺寸80x30，可自定义）
            //    if (check_collision(100, 50, 80, 30, msg.x, msg.y, 1, 1)&& P1.x <= 50 && P1.y <= 150) {
            //        state = 1;  // 切回城镇场景
            //        return;
            //    }
            //    else if (check_collision(710, 255, 60, 65, msg.x, msg.y, 1, 1) && P1.x >= 620 && P1.y >= 250&&P1.y<=320) {
            //        P1.x = 680;
            //        P1.y = 605;
            //        key_num++;
            //        state = 3;  // 切回洞穴场景
            //        return;
            //    }
            //}
            
        }
        // 传送
        if (check_collision(0, 120, 40, 30, P1.x, P1.y, 35, 28)) {
            state = 1;  // 切回城镇场景
            return;
        }
        else if (check_collision(620, 250, 80, 55, P1.x, P1.y, 35, 28) ) {
            P1.x = 680;
            P1.y = 605;
            key_num++;
            state = 3;  // 切回洞穴场景
            return;
        }
        for (int i = 0; i < barriers.size(); i++) {
            if (check_collision(barriers[i].x, barriers[i].y, barriers[i].w, barriers[i].h, P1.x, P1.y, 35, 28)) {
                c = true;
                break;
            }
            else c = false;
        }

        if (c|| P1.x<0|| P1.x>1300|| P1.y<0|| P1.y>684) {
            P1.x = oldx;
            P1.y = oldy;
        }
        if (check_collision(640, 3, 35, 28, P1.x, P1.y, 35, 28)&& P1.lifelenth<100) {
            P1.lifelenth++;
        }
        if (check_collision(minion_x, minion_y, 35, 28, P1.x, P1.y, 35, 28)) {
            P1.lifelenth--;
        }
        if (P1.lifelenth <= 0) {
            currentGameState = GAME_OVER;
            break;
        }
        
        
        putimage(0, 0, &img_bg);
        putimage(minion_x, minion_y, &img_moving_npc, SRCAND);
        putimage(minion_x, minion_y, &img_moving_npc1, SRCPAINT);
        draw_button(0, 120, 40, 30, "城镇", Color(200, 200, 200));  // 返回按钮
        //draw_button(400, 200, 80, 30, "进入洞穴", Color(200, 200, 200));
        render_health_bar(10, 10, 100, 20, P1.lifelenth, 100);
        putimage(P1.x, P1.y, &img_role, SRCAND);
        putimage(P1.x, P1.y, &img_role1, SRCPAINT);
        putimage(640, 3, &img_item_1, SRCAND);
        putimage(640, 3, &img_item_11, SRCPAINT);
        /*else if (!t2.is_takeup) {
            putimage(640, 3, &img_item_1, SRCAND);
            putimage(640, 3, &img_item_11, SRCPAINT);
        }
        else if (!t3.is_takeup) {
            putimage(640, 3, &img_item_1, SRCAND);
            putimage(640, 3, &img_item_11, SRCPAINT);
        }*/
        FlushBatchDraw();
        Sleep(10);

    }
    EndBatchDraw();
}




void drowdx() {
    if (is_palymusic)play_sound_effect("res\\beforebigboss.MP3");
    IMAGE img;
    IMAGE img1;
    IMAGE dxMap;
    IMAGE item;
    IMAGE item1;
    // 加载洞穴资源
    loadimage(&dxMap, _T("res\\background3.png"));
    loadimage(&img, _T("res\\p.png"), 35, 28);
    loadimage(&img1, _T("res\\p1.png"), 35, 28);
    loadimage(&item, "res\\crystal.png", 35, 28);
    loadimage(&item1, "res\\crystal1.png", 35, 28);

    int mapW = dxMap.getwidth();
    int mapH = dxMap.getheight();
    setbkcolor(WHITE);
    cleardevice();

    // 角色初始位置（洞穴左上角附近）
    /*P1.x = 680;
    P1.y = 605;*/
    // 障碍物（保持不变）
    //vector<barrier>barriers3 = { {0,0,1300,240},{0,240,60,444},{60,540,560,144},{780,540,519,144},{170,330,900,130},{1160,280,140,230} };
    int time = 50;
    ExMessage msg;
    while (true) {
        // 检测场景状态，若切换则退出循环
        if (state != 3) {
            break;
        }
        time--;
        if (time == 0) {
            P1.lifelenth--;
            if (P1.lifelenth <= 0) {
                currentGameState = GAME_OVER;
                return;
            }
            time = 50;
        }
        int oldX = P1.x;  // 保存原始位置
        int oldY = P1.y;
        bool is_change_pos = true;  // 默认允许移动

        // 处理消息（键盘+鼠标）
        if (peekmessage(&msg, EX_KEY)) {
            // 键盘事件：移动角色
            if (msg.message == WM_KEYDOWN) {
                // 计算新位置（先不直接修改角色坐标）
                int newX = P1.x;
                int newY = P1.y;

                switch (msg.vkcode) {
                case 'W': case 'w': newY -= 28; break;
                case 'S': case 's': newY += 28; break;
                case 'A': case 'a': newX -= 28; break;
                case 'D': case 'd': newX += 28; break;
                case VK_ESCAPE: state = 5; break;   // ESC退出程序
                }

                // 临时更新角色坐标用于碰撞检测（后续根据是否合法决定是否保留）
                P1.x = newX;
                P1.y = newY;

                if ((msg.vkcode == 't' || msg.vkcode == 'T') && (check_collision(700, 490, 35, 28, P1.x, P1.y, 35, 28) || check_collision(940, 280, 35, 28, P1.x, P1.y, 35, 28)|| check_collision(240, 280, 35, 28, P1.x, P1.y, 35, 28))) {
                    //play_sound_effect("succeed_joininggame_sound_or_takeup.MP3");
                    state = 4;
                    return;
                }
            }
            // 鼠标事件：检测「返回城镇」按钮点击
            //else if (msg.message == WM_LBUTTONDOWN) {
            //    if (check_collision(100, 50, 80, 30, msg.x, msg.y, 1, 1)) {
            //        state = 1;  // 切回城镇场景
            //        return;
            //    }
            //}
        }
        //传送
        if (check_collision(100, 50, 80, 30, P1.x, P1.y, 35, 28)) {
                    state = 1;  // 切回城镇场景
                    return;
        }

        // 1. 边界检查（防止角色出界）
        if (P1.x < 0 || P1.x > 1300 || P1.y < 0 || P1.y > 684) {
            is_change_pos = false;
        }

        // 2. 障碍物碰撞检测（只要碰撞一个就禁止移动）
        //if (is_change_pos) {
        //    for (const auto& b : barriers3) {
        //        if (check_collision(b.x, b.y, b.w, b.h, P1.x, P1.y, 35, 28)) {
        //            is_change_pos = false;
        //            break;  // 碰到一个障碍物就停止检查
        //        }
        //    }
        //}

        // 3. 根据是否允许移动，决定是否保留新位置
        if (!is_change_pos) {
            P1.x = oldX;
            P1.y = oldY;
        }

        // 4. 重绘所有元素（确保不消失，与城镇逻辑一致）
        putimage(0, 0, &dxMap);     // 绘制洞穴地图
        putimage(P1.x, P1.y, &img, SRCAND);  // 绘制角色（透明处理）
        putimage(P1.x, P1.y, &img1, SRCPAINT);
        putimage(700, 490, &item, SRCAND);  // 绘制角色（透明处理）
        putimage(700, 490, &item1, SRCPAINT);
        putimage(940, 280, &item, SRCAND);  // 绘制角色（透明处理）
        putimage(940, 280, &item1, SRCPAINT);
        putimage(240, 280, &item, SRCAND);  // 绘制角色（透明处理）
        putimage(240, 280, &item1, SRCPAINT);
        draw_button(100, 50, 80, 30, "返回城镇", Color(200, 200, 200));  // 始终显示返回按钮
        render_health_bar(10, 10, 100, 20, P1.lifelenth, 100);  // 始终显示血条
        FlushBatchDraw();  // 立即刷新画面

         
        Sleep(16);  // 控制帧率（≈60帧，与城镇保持一致）
    }
}


void render_pause_menu() {
    cleardevice();
    settextcolor(BLACK);
    outtextxy(width / 2 - 50, 100, "游戏暂停");

    int btnX = width / 2 - 100;
    int resumeY = 180, menuY = 250;
    int btnW = 200, btnH = 50;
    MOUSEMSG mouse = GetMouseMsg();

    draw_button(btnX, resumeY, btnW, btnH, "继续游戏", Color(200, 200, 200));
    draw_button(btnX, menuY, btnW, btnH, "返回菜单", Color(200, 200, 200));

    if (listen_mouse()) {
        if (check_collision(btnX, resumeY, btnW, btnH, mouse.x, mouse.y, 1, 1)) {
            switch_page(currentGameState, PLAYING);
        }
        else if (check_collision(btnX, menuY, btnW, btnH, mouse.x, mouse.y, 1, 1)) {
            switch_page(currentGameState, MENU);
        }
    }
    FlushBatchDraw();
}




/*
* 负责人：左右
* 渲染游戏结束界面
* 传入：bool isWin - 是否胜利
* 绘制游戏结束背景、胜利/失败提示、得分等
* 使用graphtool.h中的draw_button函数绘制按钮
* 返回：无
*/
void render_game_over(bool isWin) {
    cleardevice();
    settextcolor(BLACK);
    BeginBatchDraw();
    // 显示文字
    if (isWin) {
        // 胜利时显示指定对话
        IMAGE img;
        loadimage(&img, "res\\victory.png", 1300, 684);
        putimage(0, 0, &img);
    }
    else {
        IMAGE img;
        loadimage(&img, "res\\defeat.png", 1300, 684);
        putimage(0, 0, &img);
    }

    // 绘制返回菜单按钮
    int btnX = width / 2 - 100;
    int menuY = (isWin ? 520 : 250); // 胜利时按钮位置下移
    int btnW = 200, btnH = 50;

    draw_button(btnX, menuY, btnW, btnH, "返回菜单", Color(200, 200, 200));
    FlushBatchDraw();
    // 修改鼠标消息处理：非阻塞循环处理所有鼠标消息
    MOUSEMSG mouse;
    while (PeekMouseMsg(&mouse)) {
        if (mouse.uMsg == WM_LBUTTONDOWN) { // 只处理左键点击
            if (check_collision(btnX, menuY, btnW, btnH, mouse.x, mouse.y, 1, 1)) {
                P1.lifelenth = 100;
                P1.bag.num = 0;
                B1.lifelenth = 3;
                switch_page(currentGameState, MENU);
            }
        }
    }

   
}

int currentSentenceIndex = 0;   // 当前显示的句子索引
vector<string> sentences;       // 分割后的句子集合
// 将对话文本分割成句子
void split_dialog_into_sentences(const string& dialogText) {
    sentences.clear();
    currentSentenceIndex = 0;

    stringstream ss(dialogText);
    string sentence;
    char c;

    while (ss.get(c)) {
        sentence += c;
        // 根据标点符号分割句子
        if (c == '。' || c == '！' || c == '？' || c == '\n') {
            // 移除句尾空白
            while (!sentence.empty() && sentence.back() == ' ') {
                sentence.pop_back();
            }
            sentences.push_back(sentence);
            sentence.clear();
        }
    }

    // 添加最后一个句子（如果有的话）
    if (!sentence.empty()) {
        sentences.push_back(sentence);
    }
}

// 对话框渲染函数
void render_dialog(const string& dialogText, int npcId) {
    // 首次调用时分割对话
    if (sentences.empty()) {
        split_dialog_into_sentences(dialogText);
    }

    // 绘制对话框背景
    setfillcolor(RGB(240, 240, 240));
    solidrectangle(350, 142, 950, 542);

    // 绘制边框
    setlinecolor(BLACK);
    rectangle(350, 142, 950, 542);

    // 绘制NPC头像区域
    setfillcolor(RGB(220, 220, 220));
    solidrectangle(370, 162, 450, 242);
    rectangle(370, 162, 450, 242);

    // 显示NPC标识
    settextcolor(BLACK);
    settextstyle(16, 0, _T("宋体"));
    string npcName = "未知NPC";
    switch (npcId) {
    case 0:
    {
        npcName = "";
        IMAGE img;
        loadimage(&img, "res\\village_head.png", 80, 80);
        putimage(370, 162, &img);
    }
        break;
    case 1: 
    {
        npcName = ""; 
        IMAGE img;
        loadimage(&img, "res\\villager.png", 80, 80);
        putimage(370, 162, &img);
        break;
    }
    case 2: npcName = ""; break;
    case 3: npcName = ""; break;
    }
    outtextxy(370, 245, npcName.c_str());

    // 显示当前句子（如果有）
    if (currentSentenceIndex < sentences.size()) {
        string currentSentence = sentences[currentSentenceIndex];

        // 分割当前句子为多行
        const int maxLineLength = 40;
        vector<string> lines;
        string currentLine;

        for (char c : currentSentence) {
            if (currentLine.length() >= maxLineLength) {
                lines.push_back(currentLine);
                currentLine.clear();
            }
            currentLine += c;
        }
        if (!currentLine.empty()) {
            lines.push_back(currentLine);
        }

        // 绘制当前句子的行
        settextcolor(BLACK);
        settextstyle(20, 0, _T("宋体"));
        int y = 172;
        int textX = 470;

        for (const string& line : lines) {
            outtextxy(textX, y, line.c_str());
            y += 25;
            if (y > 520) break;
        }
    }

    // 显示对话进度
    char progress[50];
    sprintf_s(progress, "(%d/%d)", currentSentenceIndex + 1, sentences.size());
    outtextxy(850, 150, progress);

    // 绘制控制按钮
    // 返回按钮
    draw_button(590, 550, 100, 50, "返回", RGB(200, 200, 200));

    // 下一句按钮 - 最后一句时显示"结束"
    string nextBtnText = (currentSentenceIndex >= sentences.size() - 1) ? "结束" : "下一句";
    draw_button(710, 550, 100, 50, nextBtnText, RGB(200, 200, 200));

    // 修改鼠标消息处理：非阻塞循环处理所有鼠标消息
    MOUSEMSG mouse;
    while (PeekMouseMsg(&mouse)) {
        if (mouse.uMsg == WM_LBUTTONDOWN) { // 只处理左键点击
            // 检查返回按钮
            if (check_collision(590, 550, 100, 50, mouse.x, mouse.y, 1, 1)) {
                state = 1;
                sentences.clear();  // 清空句子集合
                currentSentenceIndex = 0;
                dialog_idx++;
                dialog_idx = dialog_idx % 2;
                
                return;
            }

            // 检查下一句按钮
            if (check_collision(710, 550, 100, 50, mouse.x, mouse.y, 1, 1)) {
                currentSentenceIndex++;
                // 如果已经是最后一句，返回游戏场景
                if (currentSentenceIndex >= sentences.size()) {
                    state = 1;
                    sentences.clear();
                    currentSentenceIndex = 0;
                    dialog_idx++;
                    dialog_idx = dialog_idx % 2;
                    
                    return;
                }
                
            }
        }
    }

    FlushBatchDraw();
}

// 其他函数保持空实现
void render_bag(const Bag& bag) {}
void render_task_list(const string tasks) {}
/*
* 负责人：左右
* 渲染游戏介绍界面
* 传入：无
* 绘制游戏背景故事、操作说明、开发者信息等
* 返回：无
*/
void render_introduction()
{
    /*cleardevice();*/
    BeginBatchDraw();
    settextcolor(BLACK);

    //显示人员、背景、操作说明、开发者信息
    outtextxy(width / 2 - 50, 50, "参与人员");
    outtextxy(width / 2 - 250, 90, "析、小小星、之一、蒂林k、张文哲、左右");

    outtextxy(width / 2 - 50, 130, "操作说明");
    outtextxy(width / 2 - 250, 170, "wasd操控人物移动、靠近物品按t键拾取物品");
    outtextxy(width / 2 - 250, 210, "靠近物品按t键拾取物品");
    outtextxy(width / 2 - 250, 250, "靠近传送门切换场景");
    int btnX = width / 2 - 100;
    int menuY = 450;
    int btnW = 200, btnH = 50;

    draw_button(btnX, menuY, btnW, btnH, "返回菜单", Color(200, 200, 200));
    FlushBatchDraw();
    // 修改鼠标消息处理：非阻塞循环处理所有鼠标消息
    MOUSEMSG mouse;
    while (PeekMouseMsg(&mouse)) {
        if (mouse.uMsg == WM_LBUTTONDOWN) { // 只处理左键点击
            if (check_collision(btnX, menuY, btnW, btnH, mouse.x, mouse.y, 1, 1)) {
                switch_page(currentGameState, MENU);
            }
        }
    }

    
}

void cleanup_renderer() { 
    cleanup_audio();
    closegraph(); }


/*
* 负责人：析
* 渲染Boss问答界面
* 传入：用全局变量const vector<string>& options
* 绘制问题背景、问题文本和选项按钮
* 使用graphtool.h中的draw_button函数绘制选项按钮
* 返回：无
*/
void render_boss_quiz(vector<question_and_answer> QAA) {
    // 静态变量保存状态（替代while循环，由主循环驱动）
    static int index = -1;                  // 当前题目索引
    static vector<string> optionTexts;      // 选项文本缓存
    static int selectedOption = -1;         // 选中的选项
    static bool answered = false;           // 是否已回答
    static bool initialized = false;        // 是否初始化
    int t_q = 100;
    if (t_q == 0) {
        P1.lifelenth--;
        if (P1.lifelenth <= 0) {
            currentGameState = GAME_OVER;
            return;
        }
        t_q = 100;
    }
    // 初始化（仅第一次调用时执行）
    if (!initialized) {
        // 随机选择题目
        if(B1.lifelenth<=3 && B1.lifelenth>0)
        {
            index = 3 - B1.lifelenth;
        }
        else {
            currentGameState = GAME_OVER;
            return;
        }
        // 预生成选项文本
        optionTexts.clear();
        optionTexts.push_back("A. " + QAA[index].chose1);
        optionTexts.push_back("B. " + QAA[index].chose2);
        optionTexts.push_back("C. " + QAA[index].chose3);
        // 重置状态
        selectedOption = -1;
        answered = false;
        initialized = true;
    }

    // 加载图片（仅一次）
    static IMAGE img;
    static bool img_loaded = false;
    if (!img_loaded) {
        loadimage(&img, "res\\bigboss.jpg", 190, 190);  // 适配窗口放大图片
        img_loaded = true;
    }

    // 处理鼠标事件（单次处理，不循环）
    ExMessage msg;
    while(peekmessage(&msg, EX_MOUSE)) {
        if (msg.message == WM_LBUTTONDOWN) {
            // 未回答时处理选项点击
            if (!answered) {
                // 选项区域：x=250-1050（宽800），y=200/280/360（高50，间距80）
                if (msg.x >= 250 && msg.x <= 1050) {
                    if (msg.y >= 200 && msg.y <= 250) selectedOption = 0;  // 选项A
                    else if (msg.y >= 280 && msg.y <= 330) selectedOption = 1;  // 选项B
                    else if (msg.y >= 360 && msg.y <= 410) selectedOption = 2;  // 选项C

                    if (selectedOption != -1) {
                        answered = true;  // 标记为已回答
                        if (selectedOption == QAA[index].answer) {
                            play_sound_effect(QAA[index].music_address);
                            if (B1.lifelenth > 0) B1.lifelenth--;  // 减少Boss生命值
                            //else if (B1.lifelenth == 0) currentGameState = GAME_OVER;
                        }
                    }
                }
            }
            // 已回答时处理返回按钮点击
            else {
                // 返回按钮区域：x=550-750，y=550-600（宽200，高50，居中）
                if (msg.x >= 550 && msg.x <= 750 && msg.y >= 550 && msg.y <= 600) {
                    // 重置状态，准备下次调用QAA[index].music_address
                    std::string stopCmd = "stop \"" + QAA[index].music_address + "\"";
                    mciSendString(stopCmd.c_str(), NULL, 0, NULL);
                    stopCmd = "colse \"" + QAA[index].music_address + "\"";
                    mciSendString(stopCmd.c_str(), NULL, 0, NULL);
                    if (B1.lifelenth == 0) currentGameState = GAME_OVER;
                    initialized = false;
                    img_loaded = false;
                    state = 3;
                    return;  // 退出当前问答界面
                }
            }
        }
    }

    // 绘制界面（单次绘制，不循环）
    cleardevice();
    setbkcolor(WHITE);
    

    // 绘制Boss图片（左上角，适配1300窗口）
    putimage(50, 50, &img);

    // 绘制题目（居中偏上，字体放大）
    settextcolor(BLACK);
    settextstyle(30, 0, _T("宋体"));
    outtextxy(300, 80, QAA[index].question.c_str());  // 右移适配图片

    // 绘制选项（宽800，高50，居中排列）
    settextstyle(24, 0, _T("宋体"));
    int optionY[] = { 200, 280, 360 };  // 选项Y坐标（间距80）
    for (int i = 0; i < 3; i++) {
        // 按钮背景（选中状态用灰色，否则白色）
        setfillcolor((selectedOption == i) ? RGB(200, 200, 200) : WHITE);
        solidrectangle(250, optionY[i], 1050, optionY[i] + 50);  // 宽800
        // 按钮边框
        setlinecolor(BLACK);
        rectangle(250, optionY[i], 1050, optionY[i] + 50);
        // 选项文本
        settextcolor(BLACK);
        outtextxy(270, optionY[i] + 10, optionTexts[i].c_str());
    }

    // 显示回答结果（已回答时）
    if (answered) {
        settextstyle(30, 0, _T("宋体"));
        if (selectedOption == QAA[index].answer) {
            settextcolor(GREEN);
            outtextxy(500, 450, _T("回答正确！"));
            
        }
        else {
            settextcolor(RED);
            outtextxy(500, 450, _T("回答错误！"));
        }

        // 绘制返回按钮（底部居中）
        setfillcolor(RGB(173, 216, 230));  // 固定浅蓝色
        solidrectangle(550, 550, 750, 600);  // 宽200，高50
        setlinecolor(BLACK);
        rectangle(550, 550, 750, 600);
        settextcolor(BLACK);
        settextstyle(24, 0, _T("宋体"));
        outtextxy(610, 560, _T("返回"));
    }

    FlushBatchDraw();
    
}


/*
* 负责人：张文哲
* 渲染游戏暂停界面
* 传入：无
* 绘制半透明遮罩、暂停菜单选项（继续游戏、重新开始、设置、返回主菜单）
* 使用graphtool.h中的draw_button函数绘制按钮
* 返回：无
*/



/*
* 负责人：张文哲
* 渲染游戏设置界面
* 传入：无
* 绘制设置选项（音量调节、按键设置、画面设置等）
* 使用graphtool.h中的draw_button和draw_dropdown函数绘制界面元素
* 返回：无
*/
void render_settings()
{
    BeginBatchDraw();
    settextcolor(BLACK);
    outtextxy(width / 2 - 30, 20, "设置");

    int btnX = width / 2 - 200;
    int resumeY = 180, menuY = 450;
    int btnW = 400, btnH = 100;

    // 绘制按钮
    draw_button(btnX, menuY - 200, btnW / 2, btnH, "+", Color(200, 200, 200));
    draw_button(btnX + btnW / 2, menuY - 200, btnW / 2, btnH, "-", Color(200, 200, 200));

    // 音乐开关按钮
    draw_button(btnX, menuY - 100, btnW, btnH, is_palymusic ? "开" : "关", Color(200, 200, 200));
    draw_button(btnX, menuY, btnW, btnH, "返回菜单", Color(200, 200, 200));
    FlushBatchDraw();
    // 非阻塞处理鼠标消息
    MOUSEMSG mouse;
    while (PeekMouseMsg(&mouse)) {
        if (mouse.uMsg == WM_LBUTTONDOWN) { // 只处理左键点击
            if (check_collision(btnX, menuY, btnW, btnH, mouse.x, mouse.y, 1, 1)) {
                switch_page(currentGameState, MENU);
            }
            else if (check_collision(btnX, menuY - 100, btnW, btnH, mouse.x, mouse.y, 1, 1)) {
                is_palymusic = !is_palymusic;
            }
            else if (check_collision(btnX, menuY - 200, btnW / 2, btnH, mouse.x, mouse.y, 1, 1)) {
                volume = min(volume + 30, 100); // 限制最大值
            }
            else if (check_collision(btnX + btnW / 2, menuY - 200, btnW / 2, btnH, mouse.x, mouse.y, 1, 1)) {
                volume = max(volume - 30, 0); // 限制最小值
            }
        }
    }

    
}


void render_game_play() {
    //int random_idx = random(0, SAT.size() - 1);
    switch (state) {
    case 1:  // 城镇场景
        drowtown();
        return;
    case 2:  // 森林场景
        drowtrees();
        return;
    case 3:  // 森林场景
        drowdx();
        return;
    case 4:  // 问答界面
        render_boss_quiz(QAA);
        return;
    case 5:
        switch_page(currentGameState, MENU);
        return;
    case 0:  // 对话界面
    {
        
        std::string dialog = SAT[dialog_idx].sayings + SAT[dialog_idx].tast;
        
        render_dialog(dialog, 0);
        return;
    }
    default: // 异常状态退出
        /*closegraph();*/
        return;
    }
}